<?xml version="1.0" encoding="iso-8859-1" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="nl">
  <head>
    <link rel="stylesheet" type="text/css" href="sfp.css" />

    <script type="text/javascript" src="external.js"></script>
    <script type="text/javascript" src="home.js"></script>

    <title>SAX Delphi XML Pascal</title>
    <meta name="Author" content="Sax for Pascal @ SourceForge.net" />
    <meta name="Keywords" content="SAX,Delphi,XML,Pascal" />
    <meta name="Description" content="SAX for Pascal is the Delphi port of the Simple API for XML Parsing interfaces." />
    <meta name="robots" content="index,follow" />
  </head>
  <body>
    <script type="text/javascript">
      <!--
      // If not loaded in frames, load the frames
      if (window.name == "") {
        location.reload ("index.html?overview.html")
      }
      // -->
    </script>
    <h1>Overview</h1>
    
    <h2>Parsing with SAX in Delphi</h2>
    <p>
      <b class="name">SAX for Pascal</b> provides a specification, in the form of a set of 
      Delphi interfaces, for parsing XML documents. 
      Your client code receives a bunch of events that tell you the contents of the XML 
      document. The main interface a SAX parser provides is <code>IXMLReader</code> (in the 
      <code>SAX.pas</code> unit). 
      This interface allows an application to set and query features and properties in the parser, 
      to register event handlers for document processing, and to initiate a document parse. You use it
      like this:
    </p>
    <pre>
<b>procedure</b> TMyContentHandler.Parse (<b>const</b> aURL : <b>string</b>);
<b>var</b>
  xmlReader : IXMLReader;
<b>begin</b>
  xmlReader := TSomeSAXParser.Create <b>as</b> IXMLReader;
  xmlReader.setContentHandler (Self);
  xmlReader.parse (aURL);
<b>end</b>;</pre>
    <p>
      One of the most important methods of <code>IXMLReader</code> is <code>setContentHandler</code>.
      With this method you register your content handler, a class that implements the 
      <code>IContentHandler</code> interface, with the parser. <code>IContentHandler</code> contains
      methods like <code>start/endDocument</code>, <code>start/endElement</code>, and
      <code>characters</code>, that the parser will call when the respective events occur.
    </p>
    
    <h2><a name="rad">SAX parsing the RAD way</a></h2>
    <p>
      Of course, the code above isn't true Rapid Application Development. That's why the 
      <b class="name">SAX for Pascal</b> packages come with components, registered on the SAX 
      tab of Delphi's Component Palette, that implement the SAX interfaces. These components are in 
      the <code>SAXComps.pas</code> unit.
      Let's look at an example, step by step.
    </p>
    <ol>
      <li>Fire up Delphi, and start a new application.</li>
      <li>Drop a <code>TSAXDelphi</code> component on the main form.</li>
      <li>Drop a <code>TSAXXMLReader</code> component on the form.</li>
      <li>Drop a <code>TSAXContentHandler</code> component on the form.</li>
      <li>
        Select <code>SAXContentHandler1</code> for the <code>ContentHandler</code> property of <br /> 
        <code>SAXXMLReader1</code>.
      </li>
      <li>
        Enter the following value for <code>SAXXMLReader1</code>'s <code>URL</code> property:<br />
      	<code>file://pathToYourFile.xml</code>.
      </li>
      <li>
        Write the following code in <code>SAXContentHandler1</code>'s <code>OnStartElement</code> 
        event:<br /> <code>MessageDlg (QName, mtInformation, [mbOk], 0);</code>
			</li>
			<li>Drop a <code>TButton</code> on the form.</li>
			<li>
			  Write the following code in <code>Button1</code>'s <code>OnClick</code> event: 
			  <code>SAXXMLReader1.Parse;</code>.
			</li>
			<li>Run the application and click the button.</li>
    </ol>
    <p>
      This will show you all the elements in the <code>pathToYourFile.xml</code> file. 
      <strong>Note:</strong> If you see question marks instead of valid element names, then refer
      to the section about <a href="#strings"><b class="sc">ansi</b> and wide strings</a> below.
    </p>
    
    <h2>More examples</h2>
    <p>
      The <b class="name">SAX for Pascal</b> <a href="downloads.html">download</a> comes 
      with several demo programs that further illustrate the use of the SAX interfaces and 
      components.
    </p>
    
    <h2><a name="vendors">Vendors</a></h2>
    <p>
      You may have noticed the <code>TSAXDelphi</code> component in the example above. It has no 
      properties, and we did nothing with it except drop it on the form. So what's its use? Well,
      <code>TSAXDelphi</code> is an example of a vendor.
    </p>
    <p>
      A <em>vendor</em> is an implementation of the <b class="name">SAX for Pascal</b>
      interfaces, i.e. a SAX parser. Take a look at the <code>Vendor</code> property of the
      <code>TSAXXMLReader</code> component. With this property, you can switch to a different
      parser. All your other code is completely independent of the parser you have choosen. In other
      words, your code won't suffer from <a rel="external" 
      href="http://www.antipatterns.com/vendorlockin.htm">vendor lock-in</a>. The vendor scheme for
      <b class="name">SAX for Pascal</b> is modeled after the vendor scheme used with Delphi's
      <code>TXMLDocument</code> component, which provides access to an XML 
      <a href="saxdom.html">DOM</a>.
    </p>
    <p>
      <b class="name">SAX for Pascal</b> comes bundled with two vendors: the 
      <code>TSAXDelphi</code> (a native Delphi parser by Keith Wood), that we encountered before, 
      and <code>TSAXMSXML</code>, an adapter to <a rel="external" 
      href="http://msdn.microsoft.com/library/en-us/xmlsdk/htm/sdk_installregister_4r76.asp">MicroSoft's 
      XML parser</a>. Other vendors exist, but they must be <a href="downloads.html">downloaded</a> 
      separately.
    </p>
    
    <h2><a name="strings"><b class="sc">Ansi</b> and wide strings</a></h2>
    <p>
      The <a rel="external" href="http://www.w3.org/TR/REC-xml#charsets">XML specification</a>
      says that any valid <a rel="external" href="http://unicode.org/">Unicode</a> character is 
      valid in XML. 
      Unicode consists of tens of thousands of characters, each of which has an unique code. To 
      be able to store any Unicode character you'll need 4 bytes (a 32-bit value) for every 
      character. This <em>encoding</em> of Unicode is called <strong>UTF-32</strong>.
    </p>
    <p>
			To simplify matters, Unicode defines allmost all commonly used characters in the first 
			65536 characters. This means that most Unicode strings can be encoded using 2 bytes (a 
			16-bit value) for every character. This encoding is called <strong>UTF-16</strong>, which in 
			Delphi is represented using <code>WideChar</code> and <code>WideString</code>.
    </p>
    <p>
			To simplify matters further, Unicode defines the first 128 characters to be identical to 
			the characters from <b class="sc">ascii</b>. An encoding that makes use of this fact is 
			<strong>UTF-8</strong>. UTF-8 is a variable length encoding with several properties that 
			make it ideal for storing Unicode when the majority of characters are <b class="sc">ascii</b> characters:
		</p>
		<ul>
		  <li>
		    It stores <b class="sc">ascii</b> characters as their <b class="sc">ascii</b> value in one byte. In other words, an <b class="sc">ascii</b><br /> 
		    string will not be changed by UTF-8.
		  </li>
		  <li>
		    Non-<b class="sc">ascii</b> character sequences are stored as more than one byte, and no <b class="sc">ascii</b><br />
		    character will be part of that sequence. In other words, functions that operate on <b class="sc">ascii</b><br />
		    strings can transparently work on UTF-8 strings. 
		  </li>
		</ul>
		<p>
		  Delphi provides some conversion routines that you may find usefull, like 
		  <code>AnsiToUtf8</code>, <code>UCS4StringToWideString</code>, <code>Utf8Decode</code>, etc.
		</p>
		<p>
		  When you expect to work with lots of international text, use <code>WideString</code>s. 
		  You should note that <code>WideStrings</code> are not reference counted on Windows (they
		  are on Linux), which makes them less effiecient to use than 
		  <code><b class="sc">Ansi</b>Strings</code>.
		  When you expect to work with text which is mostly <b class="sc">ascii</b>, but which may contain the 
		  occasional international text, use <code>UTF8Strings</code>. They use 
		  less memory and are reference counted in Delphi.
		</p>
		<p>
      <b class="name">SAX for Pascal</b> gives you the option to use either. 
      If you look in the <code>SAX.pas</code> unit, you will see the use of the 
      <code>SAX_WIDESTRINGS</code> conditional directive. It you define this in your project's 
      options, then it will use wide strings, otherwise it will use <b class="sc">ansi</b> 
      strings. The <b class="name">SAX for Pascal</b> packages are compiled with 
      <code>SAX_WIDESTRINGS</code> by default.
    </p>
    <p>
      The <code>SAX_WIDESTRINGS</code> conditional directive provides a convenient way to switch
      between <b class="sc">ansi</b> and wide strings. But what if you have used the 
      <b class="name">SAX for Pascal</b> <a href="#rad">components</a>, and have created
      event handlers? Delphi will have created code like the following:
    </p>
    <pre>
<b>procedure</b> TForm1.SAXContentHandler1Characters(Sender: TObject;
  <b>const</b> PCh: WideString);
<b>begin</b>
<b>end</b>;</pre>
    <p>
      Note the <code>WideString</code> type used. This happens because of the following definition
      in <code>SAX.pas</code>: <code>SAXString = WideString;</code>. Delphi considers 
      <code>SAXString</code> to be just an <em>alias</em> for the <code>WideString</code> type. 
      We can force Delphi to consider <code>SAXString</code> as a new type by writing 
      <code>SAXString = <b>type</b> WideString;</code> instead. This happens when your
      project's options defines <code>SAX_SEPARATETYPES</code>. So if you haven't made up your mind
      about <b class="sc">ansi</b> or wide strings, and you want to be able to switch between
      them, make sure to define <code>SAX_SEPARATETYPES</code> (and rebuild the 
      <b class="name">SAX for Pascal</b> packages).
    </p>
    
    <hr />
    <div><a href="javascript:home()">Home</a></div>
    
  </body>
</html>
